var DataType = {};

DataType.getDataTypeList = function() {
    return [
        "BIGINT UNSIGNED", "BIGINT", "INT UNSIGNED", "INT",
        "MEDIUMINT UNSIGNED", "MEDIUMINT", "SMALLINT UNSIGNED",
        "SMALLINT", "TINYINT UNSIGNED", "TINYINT", "BOOLEAN",
        "FLOAT", "DOUBLE", "DECIMAL", "CHAR", "VARCHAR","BINARY",
        "VARBINARY", "TEXT", "MEDIUMTEXT", "LONGTEXT", "DATE",
        "DATETIME", "TIMESTAMP", "TIME", "YEAR", "CLOB", "BLOB", "LONGBLOB"
    ];
};

DataType.getJavaType = function(dataType) {
    switch(dataType) {
        case "BIGINT UNSIGNED": {
            return "Long";
        }
        case "BIGINT": {
            return "Long";
        }
        case "INT UNSIGNED": {
            return "Integer";
        }
        case "INT": {
            return "Integer";
        }
        case "MEDIUMINT UNSIGNED": {
            return "Integer";
        }
        case "MEDIUMINT": {
            return "Integer";
        }
        case "SMALLINT UNSIGNED": {
            return "Integer";
        }
        case "SMALLINT": {
            return "Integer";
        }
        case "TINYINT UNSIGNED": {
            return "Integer";
        }
        case "TINYINT": {
            return "Integer";
        }
        case "BOOLEAN": {
            return "Boolean";
        }
        case "FLOAT": {
            return "Float";
        }
        case "DOUBLE": {
            return "Double";
        }
        case "DECIMAL": {
            return "BigDecimal";
        }
        case "CHAR": {
            return "String";
        }
        case "VARCHAR": {
            return "String";
        }
        case "BINARY": {
            return "InputStream";
        }
        case "VARBINARY": {
            return "Reader";
        }
        case "TEXT": {
            return "String";
        }
        case "MEDIUMTEXT": {
            return "String";
        }
        case "LONGTEXT": {
            return "String";
        }
        case "DATE": {
            return "Date";
        }
        case "DATETIME": {
            return "Date";
        }
        case "TIMESTAMP": {
            return "Date";
        }
        case "TIME": {
            return "Date";
        }
        case "YEAR": {
            return "Date";
        }
        case "CLOB": {
            return "String";
        }
        case "BLOB": {
            return "InputStream";
        }
        case "LONGBLOB": {
            return "InputStream";
        }
        default: {
            return "String";
        }
    };
};

DataType.getSqlType = function(javaType){
    if(javaType == "String") {
        return "VARCHAR(32)";
    }
    else if(javaType == "int" || javaType == "Integer") {
        return "INTEGER";
    }
    else if(javaType == "float" || javaType == "Float") {
        return "INTEGER";
    }
    else if(javaType == "double" || javaType == "Double") {
        return "DOUBLE";
    }
    else if(javaType == "long" || javaType == "Long") {
        return "LONG";
    }
    else if(javaType == "Date") {
        return "DATE|DATETIME|TIMESTAMP";
    }
    else if(javaType == "Timestamp") {
        return "TIMESTAMP";
    }
    else if(javaType == "Reader") {
        return "CLOB";
    }
    else if(javaType == "InputStream") {
        return "BLOB";
    }
    else if(javaType == "Clob") {
        return "TEXT|MEMO|CLOB";
    }
    else if(javaType == "Blob") {
        return "BLOB";
    }
    else {
        return "";
    }
};

DataType.getPrimitiveName = function(type) {
    if(type == "Character" || type == "java.lang.Character") {
        return "char";
    }
    else if(type == "Boolean" || type == "java.lang.Boolean") {
        return "boolean";
    }
    else if(type == "Byte" || type == "java.lang.Byte") {
        return "byte";
    }
    else if(type == "Short" || type == "java.lang.Short") {
        return "short";
    }
    else if(type == "Integer" || type == "java.lang.Integer") {
        return "int";
    }
    else if(type == "Float" || type == "java.lang.Float") {
        return "float";
    }
    else if(type == "Double" || type == "java.lang.Double") {
        return "double";
    }
    else if(type == "Long" || type == "java.lang.Long") {
        return "long";
    }
    return type;
};

DataType.getWrapName = function(type) {
    if(type == "char") {
        return "Character";
    }
    else if(type == "boolean") {
        return "Boolean";
    }
    else if(type == "byte") {
        return "Byte";
    }
    else if(type == "short") {
        return "Short";
    }
    else if(type == "int") {
        return "Integer";
    }
    else if(type == "float") {
        return "Float";
    }
    else if(type == "double") {
        return "Double";
    }
    else if(type == "long") {
        return "Long";
    }
    return type;
};

var MySql = {};

MySql.escape = function(source) {
    if(source == null) {
        return "";
    }

    var c;
    var buffer = [];

    for(var i = 0, length = source.length; i < length; i++) {
        c = source.charAt(i);

        switch (c) {
            case '\'': {
                buffer[buffer.length] = "\\'"; break;
            }
            case '\r': {
                buffer[buffer.length] = "\\r"; break;
            }
            case '\n': {
                buffer[buffer.length] = "\\n"; break;
            }
            case '\t': {
                buffer[buffer.length] = "\\t"; break;
            }
            case '\b': {
                buffer[buffer.length] = "\\b"; break;
            }
            case '\f': {
                buffer[buffer.length] = "\\f"; break;
            }
            case '\\': {
                buffer[buffer.length] = "\\\\"; break;
            }
            default : {
                buffer[buffer.length] = c; break;
            }
        }
    }
    return buffer.join("");
};

function TableEditor(id) {
    this.tableId = id;
    this.init();
}

TableEditor.prototype.capitalize = function(name){
    if(name == null || name.length < 1) {
        return "";
    }
    return name.charAt(0).toUpperCase() + name.substring(1);
};

TableEditor.prototype.camel = function(name){
    var s = Util.trim(name);

    if(s == "") {
        return s;
    }

    var a = s.split("_");
    var result = [];

    for(var i = 0; i < a.length; i++) {
        result[result.length] = a[i].charAt(0).toUpperCase() + a[i].substring(1).toLowerCase();
    }
    return result.join("");
};

TableEditor.prototype.insert = function(props) {
    var table = document.getElementById(this.tableId);

    if(table != null) {
        var index = -1;
        var tr = table.insertRow(index);
        var td1 = tr.insertCell(-1);
        var td2 = tr.insertCell(-1);
        var td3 = tr.insertCell(-1);
        var td4 = tr.insertCell(-1);
        var td5 = tr.insertCell(-1);
        var td6 = tr.insertCell(-1);
        var td7 = tr.insertCell(-1);
        var td8 = tr.insertCell(-1);
        var td9 = tr.insertCell(-1);
        var td10 = tr.insertCell(-1);
        var column = {
            "columnName": "unknown" + (tr.rowIndex + 1),
            "typeName": "INT",
            "columnSize": "10",
            "decimalDigits": "0",
            "columnDef": "",
            "remarks": "新建列",
            "nullable": "true",
            "autoIncrement": "false",
            "primaryKey": "false"
        };

        if(props == null || props == undefined) {
            props = {};
        }

        for(var i in props) {
            if(props[i] != null) {
                column[i] = props[i].toString();
            }
        }

        if(column.autoIncrement == "true" || column.primaryKey == "true") {
            column.columnDef = "";
            column.nullable = "false";
            column.primaryKey = "true";
        }

        td1.className = "c2";
        td1.innerHTML = (tr.rowIndex + 1);
        td2.innerHTML = "<input name=\"columnName\" type=\"text\" class=\"text2\" style=\"width: 180px;\" value=\"" + column.columnName + "\"/>";
        td3.innerHTML = "<input name=\"typeName\" type=\"text\" class=\"text2\" style=\"width: 140px;\" value=\"" + column.typeName + "\"/>";
        td4.innerHTML = "<input name=\"columnSize\" type=\"text\" class=\"text2\" style=\"width: 60px;\" value=\"" + column.columnSize + "\"/>";
        td5.innerHTML = "<input name=\"decimalDigits\" type=\"text\" class=\"text2\" style=\"width: 60px;\" value=\"" + column.decimalDigits + "\"/>";
        td6.innerHTML = "<input name=\"columnDef\" type=\"text\" class=\"text2\" style=\"width: 60px;\" value=\"" + column.columnDef + "\"/>";
        td7.innerHTML = "<input name=\"remarks\" type=\"text\" class=\"text2\" style=\"width: 152px;\" new-value=\"" + column.remarks + "\" value=\"" + column.remarks + "\"/><span name=\"remarks\" class=\"edit\"></span>";
        td8.innerHTML = "<input name=\"nullable\" type=\"checkbox\" checked-value=\"true\" value=\"" + column.nullable + "\"/>";
        td9.innerHTML = "<input name=\"autoIncrement\" type=\"checkbox\" checked-value=\"true\" value=\"" + column.autoIncrement + "\"/>";
        td10.innerHTML = "<input name=\"primaryKey\" type=\"checkbox\" checked-value=\"true\" value=\"" + column.primaryKey + "\"/>";

        td1.setAttribute("title", "新增列");
        td1.style.backgroundColor = "#ffce44";
        td2.style.width = "190px";
        td3.style.width = "150px";
        td4.style.width = "70px";
        td5.style.width = "70px";
        td6.style.width = "70px";

        td8.style.cssText = "width: 60px; text-align: center; background-color: #efefef;";
        td9.style.cssText = "width: 60px; text-align: center; background-color: #efefef;";
        td10.style.cssText = "width: 60px; text-align: center; background-color: #efefef;";
        this.registe(tr, true);

        if(index > -1) {
            table.setAttribute("selectedRowIndex", index + 1);

            for(var i = 0; i < table.rows.length; i++) {
                table.rows[i].cells[0].innerHTML = (i + 1);
            }
            this.click(table.rows[index]);
        }
        else {
            this.click(table.rows[table.rows.length - 1]);
        }
    }
};

TableEditor.prototype.clear = function() {
    this.removeColumnList = [];
    var table = document.getElementById(this.tableId);

    if(table != null) {
        var rows = table.rows;

        for(var i = rows.length - 1; i > -1; i--) {
            var tr = rows[i];
            tr.parentNode.removeChild(tr);
        }
        table.removeAttribute("selectedRowIndex");
    }
};

TableEditor.prototype.focus = function(src, event) {
    this.click(Util.getParentElement(src, "tr"));
};

TableEditor.prototype.keydown = function(src, event) {
    if(src == null || event == null) {
        return;
    }

    var e = (event || window.event);

    if(e != null) {
        var keyCode = (e.keyCode || e.which);

        if(keyCode == 37) {
            /**
             * left
             */
            if(e.ctrlKey == true) {
                var t = document.getElementById(this.tableId);

                if(t != null) {
                    var r = Util.getParentElement(src, "tr");
                    var i = Util.getParentElement(src, "td").cellIndex;

                    if(i > 1) {
                        var c = Util.getChildNode(t.rows[r.rowIndex], "/td[" + (i - 1) + "]/input");
                        this.click(Util.getParentElement(c, "tr"));
                        c.focus();
                        c.select();
                    }
                }
            }
        }
        else if(keyCode == 39) {
            /**
             * right
             */
            if(e.ctrlKey == true) {
                var t = document.getElementById(this.tableId);

                if(t != null) {
                    var r = Util.getParentElement(src, "tr");
                    var i = Util.getParentElement(src, "td").cellIndex;

                    if(i < r.cells.length - 4) {
                        var c = Util.getChildNode(t.rows[r.rowIndex], "/td[" + (i + 1) + "]/input");
                        this.click(Util.getParentElement(c, "tr"));
                        c.focus();
                        c.select();
                    }
                }
            }
        }
        else if(keyCode == 38) {
            /**
             * up
             */
            if(e.ctrlKey == true) {
                if(this.moveUp()) {
                    var t = document.getElementById(this.tableId);
                    var r = Util.getParentElement(src, "tr");
                    var c = Util.getParentElement(src, "td");
                    var d = t.rows[r.rowIndex - 1].cells[c.cellIndex];
                    Util.getChildNode(d, "input").focus();
                }
                return;
            }

            var t = document.getElementById(this.tableId);

            if(t != null) {
                var r = Util.getParentElement(src, "tr");
                var i = Util.getParentElement(src, "td").cellIndex;

                if(r.rowIndex > 0) {
                    var c = Util.getChildNode(t.rows[r.rowIndex - 1], "/td[" + i + "]/input");
                    this.click(Util.getParentElement(c, "tr"));
                    c.focus();
                    c.select();
                }
            }
        }
        else if(keyCode == 40) {
            /**
             * down
             */
            if(e.ctrlKey == true) {
                if(this.moveDown()) {
                    var t = document.getElementById(this.tableId);
                    var r = Util.getParentElement(src, "tr");
                    var c = Util.getParentElement(src, "td");
                    var d = t.rows[r.rowIndex + 1].cells[c.cellIndex];
                    Util.getChildNode(d, "input").focus();
                    Util.getChildNode(d, "input").select();
                }
                return;
            }

            var t = document.getElementById(this.tableId);

            if(t != null) {
                var r = Util.getParentElement(src, "tr");
                var i = Util.getParentElement(src, "td").cellIndex;

                if(r.rowIndex < t.rows.length - 1) {
                    var c = Util.getChildNode(t.rows[r.rowIndex + 1], "/td[" + i + "]/input");
                    this.click(Util.getParentElement(c, "tr"));
                    c.focus();
                    c.select();
                }
            }
        }
    }
};

TableEditor.prototype.click = function(src){
    if(src != null) {
        var r = src;
        var t = document.getElementById(this.tableId);

        if(t != null) {
            var index = t.getAttribute("selectedRowIndex");

            if(r.rowIndex != index) {
                if(index != null) {
                    t.rows[parseInt(index)].className = "";
                }

                t.setAttribute("selectedRowIndex", r.rowIndex);
                r.className = "hl";
            }
        }
    }
};

TableEditor.prototype.onDataLengthChange = function(src){
    if(src != null && !Util.isEmpty(src.value)) {
        if(isNaN(parseInt(src.value))) {
            alert("dataLength must be a numeric !");
            src.focus();
            src.select();
        }
    }
};

TableEditor.prototype.onDecimalDigitsChange = function(src){
    if(src != null && !Util.isEmpty(src.value)) {
        if(isNaN(parseInt(src.value))) {
            alert("decimalDigits must be a numeric !");
            src.focus();
            src.select();
        }
    }
};

TableEditor.prototype.remove = function() {
    var t = document.getElementById(this.tableId);

    if(t != null) {
        var index = t.getAttribute("selectedRowIndex");

        if(index != null) {
            var node = t.rows[parseInt(index)];
            var column = this.getChangeColumn(node);

            /**
             * 如果不是新增的列
             */
            if(column.columnName.oldValue.length > 0) {
                if(this.removeColumnList == null) {
                    this.removeColumnList = [];
                }

                /**
                 * 新名置为空, 表示删除操作
                 */
                column.columnName.newValue = "";
                this.removeColumnList[this.removeColumnList.length] = column;
            }

            node.parentNode.removeChild(node);
            t.removeAttribute("selectedRowIndex");

            for(var i = 0; i < t.rows.length; i++) {
                t.rows[i].cells[0].innerHTML = (i + 1);
            }

            if(index < t.rows.length) {
                this.click(t.rows[index]);
            }
            else {
                if(t.rows.length > 1) {
                    this.click(t.rows[index - 1]);
                }
            }
        }
    }
};

TableEditor.prototype.setColumnValue = function(r, column){
    r.setAttribute("jso", JSON.stringify(column));
    r.cells[1].childNodes[0].value = Util.trim(column.columnName);
    r.cells[2].childNodes[0].value = Util.trim(column.typeName);
    r.cells[3].childNodes[0].value = Util.trim(column.columnSize);
    r.cells[4].childNodes[0].value = Util.trim(column.decimalDigits);
    r.cells[5].childNodes[0].value = Util.trim(column.columnDef);
    r.cells[6].childNodes[0].value = Util.trim(column.remarks);
    r.cells[7].childNodes[0].checked = column.primaryKey;
    r.cells[8].childNodes[0].checked = column.nullable;
};

TableEditor.prototype.getColumn = function(r){
    var column = Util.getJso(r);

    if(column == null) {
        column = {};
    }

    column.columnName = Util.trim(r.cells[1].childNodes[0].value);
    column.typeName = Util.trim(r.cells[2].childNodes[0].value);
    column.columnSize = Util.trim(r.cells[3].childNodes[0].value);
    column.decimalDigits = Util.trim(r.cells[4].childNodes[0].value);
    column.columnDef = Util.trim(r.cells[5].childNodes[0].value);
    column.remarks = Util.trim(r.cells[6].childNodes[0].getAttribute("new-value"));
    column.nullable = r.cells[7].childNodes[0].checked;
    column.autoIncrement = r.cells[8].childNodes[0].checked;
    column.primaryKey = r.cells[9].childNodes[0].checked;
    column.orderNo = r.rowIndex;
    return column;
};

TableEditor.prototype.swap = function(r, n){
    var c1 = this.getColumn(r);
    var c2 = this.getColumn(n);
    this.setColumnValue(r, c2);
    this.setColumnValue(n, c1);
    var t = document.getElementById(this.tableId);

    if(t != null) {
        for(var i = 0; i < t.rows.length; i++) {
            t.rows[i].cells[0].innerHTML = (i + 1);
        }
    }
};

TableEditor.prototype.moveUp = function(){
    var t = document.getElementById(this.tableId);

    if(t != null) {
        var index = t.getAttribute("selectedRowIndex");

        if(index != null) {
            var i = parseInt(index);

            if(i > 0) {
                this.swap(t.rows[i], t.rows[i - 1]);
                this.click(t.rows[i - 1]);
                return true;
            }
        }
    }
    return false;
};

TableEditor.prototype.moveTop = function(){
    var t = document.getElementById(this.tableId);

    if(t != null) {
        var index = t.getAttribute("selectedRowIndex");

        if(index != null) {
            var i = parseInt(index);

            if(i > 0) {
                for(var j = i; j > 1; j--) {
                    this.swap(t.rows[j], t.rows[j - 1]);
                }

                this.click(t.rows[0]);
                return true;
            }
        }
    }
    return false;
};

TableEditor.prototype.moveDown = function(){
    var t = document.getElementById(this.tableId);

    if(t != null) {
        var index = t.getAttribute("selectedRowIndex");

        if(index != null) {
            var i = parseInt(index);

            if(i < t.rows.length - 1) {
                this.swap(t.rows[i], t.rows[i + 1]);
                this.click(t.rows[i + 1]);
                return true;
            }
        }
    }
    return false;
};

TableEditor.prototype.moveBottom = function(){
    var t = document.getElementById(this.tableId);

    if(t != null) {
        var index = t.getAttribute("selectedRowIndex");

        if(index != null) {
            var i = parseInt(index);

            if(i < t.rows.length - 1) {
                for(var j = i; j < t.rows.length - 1; j++) {
                    this.swap(t.rows[j], t.rows[j + 1]);
                }

                this.click(t.rows[t.rows.length - 1]);
                return true;
            }
        }
    }
    return false;
};

TableEditor.prototype.getColumnList = function(filter){
    var columnList = [];
    var table = document.getElementById(this.tableId);

    if(table != null) {
        var rows = table.rows;

        for(var i = 0; i < rows.length; i++) {
            var column = this.getColumn(rows[i]);

            if(Util.trim(column.columnCode) == "") {
                continue;
            }

            if(filter == null || filter(column)) {
                columnList[columnList.length] = column;
            }
        }
    }
    return columnList;
};

TableEditor.prototype.getTableChange = function() {
    var table = {};
    var tableName = jQuery("#comment-panel input[name=tableName]");
    var remarks = jQuery("#comment-panel textarea[name=remarks]");

    table.tableName = {"oldValue": tableName.attr("old-value"), "newValue": tableName.val()};
    table.remarks = {"oldValue": remarks.attr("old-value"), "newValue": remarks.val()};
    return table;
};

TableEditor.prototype.getChangeList = function() {
    var self = this;
    var changeList = [];
    var removeColumnList = this.removeColumnList;

    if(removeColumnList != null) {
        for(var i = 0; i < removeColumnList.length; i++) {
            changeList[changeList.length] = removeColumnList[i];
        }
    }

    jQuery("#" + this.tableId + " tr").each(function() {
        changeList[changeList.length] = self.getChangeColumn(this);
    });
    return changeList;
};

TableEditor.prototype.getChangeColumn = function(e) {
    var column = {};
    var columnName = jQuery(e).find("input[name=columnName]");
    var typeName = jQuery(e).find("input[name=typeName]");
    var columnSize = jQuery(e).find("input[name=columnSize]");
    var decimalDigits = jQuery(e).find("input[name=decimalDigits]");
    var columnDef = jQuery(e).find("input[name=columnDef]");
    var remarks = jQuery(e).find("input[name=remarks]");
    var nullable = jQuery(e).find("input[name=nullable]");
    var autoIncrement = jQuery(e).find("input[name=autoIncrement]");
    var primaryKey = jQuery(e).find("input[name=primaryKey]");

    column.columnName = {"oldValue": columnName.attr("old-value"), "newValue": columnName.val()};
    column.typeName = {"oldValue": typeName.attr("old-value"), "newValue": typeName.val()};
    column.columnSize = {"oldValue": columnSize.attr("old-value"), "newValue": columnSize.val()};
    column.decimalDigits = {"oldValue": decimalDigits.attr("old-value"), "newValue": decimalDigits.val()};
    column.columnDef = {"oldValue": columnDef.attr("old-value"), "newValue": columnDef.val()};
    column.remarks = {"oldValue": remarks.attr("old-value"), "newValue": remarks.attr("new-value")};
    column.nullable = {"oldValue": nullable.attr("old-value"), "newValue": nullable.prop("checked").toString()};
    column.autoIncrement = {"oldValue": autoIncrement.attr("old-value"), "newValue": autoIncrement.prop("checked").toString()};
    column.primaryKey = {"oldValue": primaryKey.attr("old-value"), "newValue": primaryKey.prop("checked").toString()};

    for(var name in column) {
        var prop = column[name];

        if(prop.oldValue == null) {
            prop.oldValue = "";
        }
        else {
            prop.oldValue = prop.oldValue.toString();
        }

        if(prop.newValue == null) {
            prop.newValue = "";
        }
        else {
            prop.newValue = prop.newValue.toString();
        }
    }
    return column;
};

TableEditor.prototype.init = function() {
    var self = this;

    jQuery("#" + this.tableId).find("tr").each(function() {
        self.registe(this, false);
    });
};

TableEditor.prototype.registe = function(tr, create) {
    var self = this;

    /**
     * all
     */
    jQuery(tr).click(function() {
        self.click(this);
    });

    jQuery(tr).find("td input").each(function() {
        if(this.type == "checkbox" || this.type == "radio") {
            this.checked = (this.value == "true");

            if(create == true) {
                this.setAttribute("old-value", "false");
            }
            else {
                this.setAttribute("old-value", this.checked);
            }
        }
        else {
            if(create == true) {
                this.setAttribute("old-value", "");
            }
            else {
                var newValue = this.getAttribute("new-value");

                if(newValue != null) {
                    this.setAttribute("old-value", newValue);
                }
                else {
                    this.setAttribute("old-value", this.value);
                }
            }
        }
    });

    jQuery(tr).find("td input[type=text]").focus(function() {
        self.focus(this);
    });

    jQuery(tr).find("td input[type=text]").keyup(function(event) {
        self.keydown(this, event);
    });

    /**
     * columnSize
     */
    jQuery(tr).find("td input[name=columnSize]").change(function() {
        self.onDataLengthChange(this);
    });

    /**
     * decimalDigits
     */
    jQuery(tr).find("td input[name=decimalDigits]").change(function() {
        self.onDecimalDigitsChange(this);
    });

    /**
     * remarks
     */
    jQuery(tr).find("td input[name=remarks]").change(function() {
        this.setAttribute("new-value", this.value);
    });

    jQuery(tr).find("td span.edit[name=remarks]").click(function() {
        var remarks = jQuery(this).siblings("input[name=remarks]");
        var position = remarks.position();
        jQuery("#edit-panel textarea[name=content]").val(remarks.attr("new-value"));
        jQuery("#edit-panel textarea[name=content]").css({"width": "300px", "height": "100px"});

        jQuery("#edit-panel").css({"top": (position.top + 22) + "px", "left": position.left + "px"});
        jQuery("#edit-panel").show();

        jQuery("#edit-panel textarea[name=content]").unbind();
        jQuery("#edit-panel textarea[name=content]").blur(function() {
            jQuery("#edit-panel").hide();
        });

        jQuery("#edit-panel textarea[name=content]").change(function() {
            var value = jQuery(this).val();
            remarks.val(value);
            remarks.attr("new-value", value);
            jQuery("#edit-panel").hide();
        });
        jQuery("#edit-panel textarea[name=content]").focus();
    });

    /**
     * primaryKey
     */
    jQuery(tr).find("td input[name=nullable]").click(function() {
        if(this.checked == true) {
            var autoIncrement = jQuery(this).closest("tr").find("input[name=autoIncrement]");
            var primaryKey = jQuery(this).closest("tr").find("input[name=primaryKey]");
    
            if(autoIncrement.prop("checked") == true || primaryKey.prop("checked") == true) {
                this.checked = false;
            }
        }
    });

    /**
     * primaryKey
     */
    jQuery(tr).find("td input[name=autoIncrement], td input[name=primaryKey]").click(function() {
        var tr = jQuery(this).closest("tr");
        var nullable = tr.find("input[name=nullable]");
        var primaryKey = tr.find("input[name=primaryKey]");
        var autoIncrement = tr.find("input[name=autoIncrement]");

        if(this.checked == true) {
            nullable.prop("checked", false);
        }

        if(this.name == "autoIncrement" && this.checked == true) {
            jQuery(this).closest("table").find("tr td input[name=autoIncrement]").prop("checked", false);
            primaryKey.prop("checked", true);
            this.checked = true;
        }

        if(this.name == "primaryKey" && this.checked == false) {
            if(autoIncrement.prop("checked") == true) {
                this.checked = true;
            }
        }
    });

    jQuery(tr).find("td select[name=typeName]").each(function() {
        var e = this;

        for(var i = e.length - 1; i > -1; i--) {
            e.options.remove(i);
        }

        var flag = false;
        var selected = e.getAttribute("selected-value");
        var dataTypeList = DataType.getDataTypeList();

        if(selected != null) {
            selected = selected.toLowerCase();
        }

        for(var i = 0; i < dataTypeList.length; i++) {
            var dataType = dataTypeList[i];
            var option = new Option(dataType, dataType);

            if(selected == dataType.toLowerCase()) {
                option.selected = true;
            }
            e.options.add(option);
        }
    });
};

TableEditor.prototype.setProperty = function(name, value) {
    if(name == "tableName") {
        return jQuery("#comment-panel input[name=tableName]").val(value);
    }
    else if(name == "remarks") {
        return jQuery("#comment-panel textarea[name=remarks]").val(value)
    }
    else {
        return null;
    }
};

TableEditor.prototype.getProperty = function(name) {
    if(name == "tableName") {
        return jQuery("#comment-panel input[name=tableName]").val();
    }
    else if(name == "remarks") {
        return jQuery("#comment-panel textarea[name=remarks]").val()
    }
    else {
        return null;
    }
};

var IndexEditor = function(tableId) {
    this.tableId = tableId;
    this.init();
};

IndexEditor.prototype.click = function(src) {
    if(src != null) {
        var r = src;
        var t = document.getElementById(this.tableId);

        if(t != null) {
            var index = t.getAttribute("selectedRowIndex");

            if(r.rowIndex != index) {
                if(index != null) {
                    t.rows[parseInt(index)].className = "";
                }

                t.setAttribute("selectedRowIndex", r.rowIndex);
                r.className = "hl";
            }
        }
    }
};

IndexEditor.prototype.getChangeList = function() {
    var self = this;
    var changeList = [];
    var removeIndexList = this.removeIndexList;

    if(removeIndexList != null) {
        for(var i = 0; i < removeIndexList.length; i++) {
            changeList[changeList.length] = removeIndexList[i];
        }
    }

    jQuery("#" + this.tableId + " tr").each(function() {
        if(this.rowIndex > 0) {
            changeList[changeList.length] = self.getChangeIndex(this);
        }
    });
    return changeList;
};

IndexEditor.prototype.getChangeIndex = function(e) {
    var indexInfo = {};
    var indexName = jQuery(e).find("input[name=indexName]");
    var columnName = jQuery(e).find("input[name=columnName]");
    var nonUnique = jQuery(e).find("select[name=nonUnique]");
    var indexType = jQuery(e).find("select[name=indexType]");

    indexInfo.indexName = {"oldValue": indexName.attr("old-value"), "newValue": indexName.val()};
    indexInfo.columnName = {"oldValue": columnName.attr("old-value"), "newValue": columnName.val()};
    indexInfo.nonUnique = {"oldValue": nonUnique.attr("old-value"), "newValue": nonUnique.val()};
    indexInfo.indexType = {"oldValue": indexType.attr("old-value"), "newValue": indexType.val()};

    for(var name in indexInfo) {
        var prop = indexInfo[name];

        if(prop.oldValue == null) {
            prop.oldValue = "";
        }
        else {
            prop.oldValue = prop.oldValue.toString();
        }

        if(prop.newValue == null) {
            prop.newValue = "";
        }
        else {
            prop.newValue = prop.newValue.toString();
        }
    }
    return indexInfo;
};

IndexEditor.prototype.insert = function(props) {
    var table = document.getElementById(this.tableId);

    if(table != null) {
        var index = -1;
        var tr = table.insertRow(index);
        var td1 = tr.insertCell(-1);
        var td2 = tr.insertCell(-1);
        var td3 = tr.insertCell(-1);
        var td4 = tr.insertCell(-1);
        var td5 = tr.insertCell(-1);
        var indexInfo = {
            "indexName": "idx_" + (tr.rowIndex + 1),
            "columnName": "unknown",
            "nonUnique": "INT",
            "indexType": ""
        };

        if(props == null || props == undefined) {
            props = {};
        }

        for(var i in props) {
            if(props[i] != null) {
                indexInfo[i] = props[i].toString();
            }
        }

        td1.className = "c2";
        td1.innerHTML = tr.rowIndex;
        td2.innerHTML = "<input name=\"indexName\" type=\"text\" class=\"text2\" style=\"width: 190px;\" value=\"" + indexInfo.indexName + "\"/>";
        td3.innerHTML = "<input name=\"columnName\" type=\"text\" class=\"text2\" style=\"width: 290px;\" value=\"" + indexInfo.columnName + "\"/>";
        td4.innerHTML = [
            "<select name=\"nonUnique\" style=\"width: 120px;\" selected-value=\"" + indexInfo.nonUnique + "\">",
            "<option value=\"1\">默认</option>",
            "<option value=\"0\">Unique</option>",
            "<option value=\"2\">Fulltext</option>",
            "<option value=\"3\">Spatial</option>",
            "</select>"].join("");

        td5.innerHTML = [
            "<select name=\"indexType\" style=\"width: 120px;\" selected-value=\"" + indexInfo.indexType + "\">",
            "<option value=\"\">默认</option>",
            "<option value=\"BTREE\">BTREE</option>",
            "<option value=\"HASH\">HASH</option>",
            "</select>"].join("");

        this.registe(tr, true);

        if(index > -1) {
            table.setAttribute("selectedRowIndex", index + 1);

            for(var i = 1; i < table.rows.length; i++) {
                table.rows[i].cells[0].innerHTML = i;
            }
            this.click(table.rows[index]);
        }
        else {
            this.click(table.rows[table.rows.length - 1]);
        }
    }
};

IndexEditor.prototype.remove = function() {
    var t = document.getElementById(this.tableId);

    if(t != null) {
        var index = t.getAttribute("selectedRowIndex");

        if(index != null) {
            var node = t.rows[parseInt(index)];
            var indexInfo = this.getChangeIndex(node);

            /**
             * 如果不是新增的索引
             */
            if(indexInfo.indexName.oldValue.length > 0) {
                if(this.removeIndexList == null) {
                    this.removeIndexList = [];
                }

                /**
                 * 新名置为空, 表示删除操作
                 */
                indexInfo.indexName.newValue = "";
                this.removeIndexList[this.removeIndexList.length] = indexInfo;
            }

            node.parentNode.removeChild(node);
            t.removeAttribute("selectedRowIndex");

            for(var i = 1; i < t.rows.length; i++) {
                t.rows[i].cells[0].innerHTML = i;
            }

            if(index < t.rows.length) {
                this.click(t.rows[index]);
            }
            else {
                if(t.rows.length > 1) {
                    this.click(t.rows[index - 1]);
                }
            }
        }
    }
};

IndexEditor.prototype.clear = function() {
    this.removeColumnList = [];
    var table = document.getElementById(this.tableId);

    if(table != null) {
        var rows = table.rows;

        for(var i = rows.length - 1; i > 0; i--) {
            var tr = rows[i];
            tr.parentNode.removeChild(tr);
        }
        table.removeAttribute("selectedRowIndex");
    }
};

IndexEditor.prototype.registe = function(tr, create) {
    var self = this;

    jQuery(tr).find("td select").each(function() {
        var selectedValue = this.getAttribute("selected-value");

        if(selectedValue != null) {
            var options = this.options;

            for(var i = 0; i < options.length; i++) {
                if(options[i].value == selectedValue) {
                    this.value = selectedValue;
                    break;
                }
            }
            this.setAttribute("old-value", selectedValue);
        }
        else {
            this.setAttribute("old-value", this.value);
        }
        if(create == true) {
            this.setAttribute("old-value", "");
        }
    });

    jQuery(tr).find("td input").each(function() {
        if(this.type == "checkbox" || this.type == "radio") {
            this.checked = (this.value == "true");

            if(create == true) {
                this.setAttribute("old-value", "false");
            }
            else {
                this.setAttribute("old-value", this.checked);
            }
        }
        else {
            if(create == true) {
                this.setAttribute("old-value", "");
            }
            else {
                var newValue = this.getAttribute("new-value");

                if(newValue != null) {
                    this.setAttribute("old-value", newValue);
                }
                else {
                    this.setAttribute("old-value", this.value);
                }
            }
        }
    });

    jQuery(tr).click(function(event) {
        self.click(this);
    });
};

IndexEditor.prototype.init = function() {
    var self = this;
    var tableId = this.tableId;

    jQuery("#" + tableId).find("tr").each(function() {
        self.registe(this, false);
    });

    jQuery("#insert-index-btn").click(function() {
        self.insert();
    });

    jQuery("#delete-index-btn").click(function() {
        self.remove();
    });
};

/**
 * 事件处理
 */
jQuery(function() {
    var tableId = "column-table";
    var tableEditor = new TableEditor(tableId);
    var indexEditor = new IndexEditor("index-table");
    Dragable.registe("alter-panel");

    var validate = function() {
        var oldTableName = jQuery("input[name=tableName]").attr("old-value");
        var newTableName = jQuery("input[name=tableName]").val();
        var indexList = indexEditor.getChangeList();
        var columnList = tableEditor.getChangeList();

        if(jQuery.trim(newTableName).length < 1) {
            return "表名不能为空！";
        }

        if(columnList.length < 1) {
            return "请至少添加一列！";
        }

        for(var i = 0; i < columnList.length; i++) {
            var column = columnList[i];
            var columnName = column.columnName;

            if(columnName.oldValue.length < 1 && columnName.newValue.length < 1) {
                return "列名不能为空！";
            }
        }

        for(var i = 0; i < indexList.length; i++) {
            var indexInfo = indexList[i];
            var indexName = indexInfo.indexName;

            if(indexName.oldValue.length < 1 && indexName.newValue.length < 1) {
                return "索引名不能为空！";
            }
        }
        return null;
    };

    var getParameters = function() {
        var params = [];
        var name = PageContext.getAttribute("connectionName");
        var database = PageContext.getAttribute("database");
        var action = PageContext.getAttribute("action");
        var remarks = jQuery("textarea[name=textarea]").val();
        var indexList = indexEditor.getChangeList();
        var columnList = tableEditor.getChangeList();
        var tableChange = tableEditor.getTableChange();

        params[params.length] = "name=" + encodeURIComponent(name);
        params[params.length] = "database=" + encodeURIComponent(database);
        params[params.length] = "action=" + action;
        params[params.length] = "tableDefinition=" + encodeURIComponent(JSON.stringify(tableChange));
        params[params.length] = "columnDefinition=" + encodeURIComponent(JSON.stringify(columnList));
        params[params.length] = "indexDefinition=" + encodeURIComponent(JSON.stringify(indexList));
        return params.join("&");
    };

    jQuery("#insert-column-btn").click(function() {
        tableEditor.insert();
    });

    jQuery("#delete-column-btn").click(function() {
        tableEditor.remove();
    });

    jQuery("#save-column-btn, #save-index-btn, #save-table-btn").click(function() {
        var message = validate();

        if(message != null) {
            AlterPanel.error(message);
            return;
        }

        AlterPanel.loading();
        var params = getParameters();

        jQuery.ajax({
            "type": "post",
            "url": PageContext.getContextPath() + "/webcat/table/getAlterSql.html",
            "dataType": "json",
            "data": params,
            "error": function() {
                AlterPanel.error("系统错误，请稍后再试！");
            },
            "success": function(result) {
                /**
                 * 为了显示loading效果, 此处稍等一会再显示
                 */
                setTimeout(function() {
                    AlterPanel.setEnabled(true);

                    if(result.status != 200) {
                        AlterPanel.error(result.message);
                        return;
                    }

                    var value = result.value;

                    if(value.length < 1) {
                        AlterPanel.show("您没有做任何修改，无需提交！");
                        return;
                    }
                    else {
                        AlterPanel.submit(Sql.highlight(value + "\r\n\r\n\r\n\r\n"));
                    }
                }, 500);
            }
        });
    });

    var tabPanel = new TabPanel({"container": "table-edit-panel"});
    var sqlParsePanel = new SqlParsePanel();

    sqlParsePanel.callback = function(text) {
        var self = this;

        if(text == null || jQuery.trim(text).length < 1) {
            self.error("请输入创建脚本！");
            return;
        }

        jQuery.ajax({
            "type": "post",
            "url": PageContext.getContextPath() + "/webcat/table/parse.html",
            "dataType": "json",
            "data": "sql=" + encodeURIComponent(text),
            "error": function() {
                self.error("系统错误，请稍后再试！");
            },
            "success": function(result) {
                if(result.status != 200) {
                    self.error(result.message);
                    return;
                }

                var table = result.value;
                var columns = table.columns;
                var indexs = table.indexs;
                tableEditor.clear();
                indexEditor.clear();

                for(var i = 0; i < columns.length; i++) {
                    tableEditor.insert(columns[i]);
                }

                for(var i = 0; i < indexs.length; i++) {
                    indexEditor.insert(indexs[i]);
                }

                tableEditor.setProperty("tableName", table.tableName);
                tableEditor.setProperty("remarks", table.remarks);
                self.close();
            }
        });
    };

    /**
     * 导入建表语句
     */
    jQuery("#parse-sql-btn").click(function() {
        sqlParsePanel.open("请输入创建脚本！");
    });

    jQuery("#alter-panel a.select").click(function() {
        DomUtil.select(jQuery("#alter-panel").find(".sql-editor").get(0));
    });

    jQuery("#alter-panel input.ensure").click(function() {
        var src = jQuery(this);
        var params = getParameters();
        AlterPanel.running();

        jQuery.ajax({
            "type": "post",
            "url": PageContext.getContextPath() + "/webcat/table/alter.html",
            "dataType": "json",
            "data": params,
            "error": function() {
                AlterPanel.error("系统错误，请稍后再试！");
                AlterPanel.setEnabled(true);
            },
            "success": function(result) {
                var content = [];

                if(result.status == 200) {
                    content[content.length] = "<div class=\"info\"><p>执行成功，点击 [关闭] 将刷新页面，否则请关闭对话框！</p></div>";
                }
                else {
                    content[content.length] = "<div class=\"error\"><p>执行失败，点击 [关闭] 将刷新页面，否则请关闭对话框！</p></div>";
                }

                content[content.length] = "<div>" + result.message + "</div>";

                jQuery("#alter-panel input.cancel").unbind();
                jQuery("#alter-panel input.cancel").click(function() {
                    var name = PageContext.getAttribute("connectionName");
                    var database = PageContext.getAttribute("database");

                    var params = [];
                    params[params.length] = "name=" + encodeURIComponent(name);
                    params[params.length] = "database=" + encodeURIComponent(database);
                    window.location.href = PageContext.getContextPath() + "/webcat/table/list.html?" + params.join("&");
                });
                AlterPanel.show(content.join(""));
            }
        });
    });

    jQuery("#alter-panel input.cancel").click(function() {
        jQuery("#alter-panel").hide();
    });

    jQuery("#alter-panel div.panel div.panel-title span.close").click(function() {
        jQuery("#alter-panel").hide();
    });

    jQuery("#sql-script-panel div.menu-bar .select").click(function() {
        DomUtil.select(jQuery("#sql-script-panel .sql-editor").get(0));
    });

    jQuery("#sql-script-panel").bind("active", function() {
        var params = getParameters();
        var src = jQuery(this).find(".sql-editor");
        src.html("<div><img src=\"" + PageContext.getContextPath() + "/resource/widget/images/loading.gif\"/></div>");

        jQuery.ajax({
            "type": "post",
            "url": PageContext.getContextPath() + "/webcat/table/getCreateSql.html",
            "dataType": "json",
            "data": params,
            "error": function() {
                src.html("系统错误，请稍后再试！");
            },
            "success": function(result) {
                src.html(Sql.highlight(result.value));
            }
        });
    });

    var action = PageContext.getAttribute("action");

    if(action != "create") {
        jQuery("#parse-sql-btn").remove();
    }

    if(action == "create") {
        jQuery("#parse-sql-btn").show();
        jQuery("#comment-panel input[name=tableName]").val("mytable1");
        jQuery("#comment-panel textarea[name=remarks]").val("新建表");

        tableEditor.insert({
            "columnName": "id",
            "typeName": "BIGINT",
            "columnSize": "20",
            "decimalDigits": "0",
            "columnDef": "0",
            "remarks": "主键",
            "nullable": "false",
            "autoIncrement": "true",
            "primaryKey": "true"
        });

        tableEditor.insert({
            "columnName": "create_time",
            "typeName": "DATETIME",
            "columnSize": "0",
            "decimalDigits": "0",
            "columnDef": "",
            "remarks": "创建时间",
            "nullable": "false",
            "autoIncrement": "false",
            "primaryKey": "false"
        });

        tableEditor.insert({
            "columnName": "update_time",
            "typeName": "DATETIME",
            "columnSize": "0",
            "decimalDigits": "0",
            "columnDef": "",
            "remarks": "创建时间",
            "nullable": "false",
            "autoIncrement": "false",
            "primaryKey": "false"
        });
    }
});
